
/**
 * 自定义可编辑面板
 * 
 * @class Ext.ux.SimpleEditorGridPanel
 * @extends Ext.grid.EditorGridPanel
 */
Ext.ux.SimpleEditorGridPanel = Ext.extend(Ext.grid.EditorGridPanel, {
	beanName : null,// 域对象名称，方便构造CRUD的URL地址，基于规约编程
	actionSuffix : '.action',// CRUD的URL后缀
	defaultAction : true,// 是否自动生成处理CRUD的Action地址，默认为true

	selectAction : null,// 查询操作地址
	beforeSelect : null,// 查询之前调用的函数，返回false，终止后面的操作，无参数
	afterSelect : null,// 查询之后调用的函数，返回false，终止后面的操作，参数：Ajax调用返回的JSON字符串

	updateAction : null,// 更新操作地址
	beforeUpdate : null,// 更新之前调用的函数，返回false，终止后面的操作，参数：e，跟EditorGridPanel的afteredit参数相同
	afterUpdate : null,// 更新之后调用的函数，返回false，终止后面的操作，参数：Ajax调用返回的JSON字符串

	deleteAction : null,// 删除操作地址
	beforeDelete : null,// 删除之前调用的函数，返回false，终止后面的操作，无参数
	afterDelete : null,// 删除之后调用的函数，返回false，终止后面的操作，参数：Ajax调用返回的JSON字符串

	insertAction : null,// 插入操作地址 TODO 需要弹出新建页面，目前实现是直接在列表上新增一行空记录
	beforeInsert : null,// 插入之前调用的函数，返回false，终止后面的操作，无参数
	afterInsert : null,// 插入之后调用的函数，返回false，终止后面的操作，参数：Ajax调用返回的JSON字符串

	smType : null,// 选择模式，常量取值见后
	pageSize : null,// 是否分页，如果不为null，表示分页，值为每页记录数，否则不分页
	metaData : null,// 元数据定义，包括属性：header, name, type, editor,
	// render等，同ColumnModel
	data : null,// 来自内存的数据定义，参见SimpleStore的data属性
	remoteSort : false,// 是否启用后台排序，默认不启用
	displayRowNum : false,// 是否显示行号列，默认不显示

	dynamicCol : false,//动态列，必须指定selectAction TODO
	initComponent : function() {
		//beanName是必须属性，用它约定一些操作链接，ID列名等
		if (!this.beanName) {
			throw new Error('初始化失败：缺少对象名称');
		}

		//把beanName的第一个字母转换成大写
		var BeanName = this.beanName.substring(0, 1).toUpperCase()
				+ this.beanName.substring(1, this.beanName.length);
		//查询操作		
		var selectAction = this.selectAction;
		if (this.defaultAction && !selectAction) {
			selectAction = 'query' + BeanName + this.actionSuffix;
		}
		//删除操作
		var deleteAction = this.deleteAction;
		if (this.defaultAction && !deleteAction) {
			deleteAction = 'delete' + BeanName + this.actionSuffix;
		}
		//更新操作
		var updateAction = this.updateAction;
		if (this.defaultAction && !updateAction) {
			updateAction = 'update' + BeanName + this.actionSuffix;
		}
		//新建操作
		var insertAction = this.insertAction;
		if (this.defaultAction && !insertAction) {
			insertAction = 'insert' + BeanName + this.actionSuffix;
		}

		// 复选框选择模式
		var chkSm = new Ext.grid.CheckboxSelectionModel();
		// 行号列
		var rowNumber = new Ext.grid.RowNumberer();

		// 列模式定义
		var newCm = null;
		if (this.metaData) {
			var metaData4CM = [];
			for (var i = 0; i < this.metaData.length; i++) {
				// 没有指定header属性的不加入列模式，只是作为数据列
				if (!this.metaData[i].header) {
					continue;
				}

				var tempObj = {};
				//复制属性
				for (var prop in this.metaData[i]) {
					tempObj[prop] = this.metaData[i][prop];
				}
				metaData4CM.push(tempObj);
			}

			//含有复选框列，置于第一列，并定义与数据选择/取消选择的事件关联
			if (this.smType
					&& this.smType == Ext.ux.SimpleEditorGridPanel.CHECKBOX_SELECT) {
				metaData4CM.unshift(chkSm);
				//解决复选框选择模式的一个BUG:选中行同时改变了Checkbox的状态
				chkSm.handleMouseDown = Ext.emptyFn;
				//解决复选框选择模式的一个BUG:全选复选框不会实时更新
				chkSm.addListener('rowselect', function(sm, rowIndex, record) {
					if (this.grid.getStore().getTotalCount() == this.getCount()) {
						Ext.get(Ext.query('.x-grid3-hd-checker')[0])
								.addClass('x-grid3-hd-checker-on');
					}
				}, chkSm);
				chkSm.addListener('rowdeselect',
						function(sm, rowIndex, record) {
							Ext.get(Ext.query('.x-grid3-hd-checker')[0])
									.removeClass('x-grid3-hd-checker-on');
						}, chkSm);
			} else {
				if (this.displayRowNum) {
					metaData4CM.unshift(rowNumber);
				}
			}
			//创建列模式
			newCm = new Ext.grid.ColumnModel(metaData4CM);
		}
		var cm = this.cm || newCm;
		if (!cm) {
			throw new Error('初始化失败：缺少元数据定义');
		}

		// 数据源定义
		var newDs = null;
		var mode = 'remote';
		if (this.metaData) {
			if (this.data) {
				// 内存数据时取消可编辑功能
				for (var i = 0; i < cm.getColumnCount(); i++) {
					if (cm.isCellEditable(i, 0)) {
						cm.setEditable(i, false);
					}
				}

				var fields = [];
				// 考虑行号，复选框也同样占用一列
				if (this.smType == Ext.ux.SimpleEditorGridPanel.CHECKBOX_SELECT
						|| this.displayRowNum) {
					for (var i = 0; i < this.data.length; i++) {
						this.data[i].unshift('');
					}
				}
				for (var i = 0; i < this.metaData.length; i++) {
					fields.push(this.metaData[i].name);
				}

				// 数据来自内存
				var simpleStore = new Ext.data.SimpleStore({
							proxy : new Ext.data.MemoryProxy(),
							fields : fields,
							data : this.data
						})
				newDs = simpleStore;
				mode = 'local';
			} else {
				// 数据来自服务器端
				var params = null;
				if (this.pageSize) {
					params = {
						totalProperty : 'totalProperty',
						root : 'root'
					};
				} else {
					params = {
						root : this.beanName + 'List'
					};
				}

				newDs = new Ext.data.Store({
							remoteSort : this.remoteSort,
							url : selectAction,
							reader : new Ext.data.JsonReader(params,
									this.metaData)
						});
				if (!newDs || !selectAction) {
					throw new Error('初始化失败：缺少数据源定义');
				}
			}
		}
		var ds = this.ds || newDs;
		if (!ds) {
			throw new Error('初始化失败：缺少数据源定义');
		}

		// 选择模式定义
		var newSm = null;
		if (this.smType) {
			switch (this.smType) {
				case Ext.ux.SimpleEditorGridPanel.SINGLE_SELECT : //单选模式
					newSm = new Ext.grid.RowSelectionModel({
								singleSelect : true
							});
					break;
				case Ext.ux.SimpleEditorGridPanel.MULTI_SELECT : //多选模式
					newSm = new Ext.grid.RowSelectionModel({
								singleSelect : false
							});
					break;
				case Ext.ux.SimpleEditorGridPanel.CHECKBOX_SELECT : //复选框多选模式
					newSm = chkSm;
					break;
				default :
					break;
			}
		}
		var sm = this.sm || newSm;

		// 分页栏
		var pagingToolbar = null;
		if (this.pageSize) {
			pagingToolbar = new Ext.PagingToolbar({
						pageSize : this.pageSize,
						store : ds,
						displayInfo : true,
						displayMsg : '第 {0} - {1} 条  共 {2} 条',
						emptyMsg : "没有记录"
					});
		}
		if (pagingToolbar) {
			Ext.apply(this, {
						bbar : pagingToolbar
					});
		}

		// 工具栏
		var buttonArr = [], empty = true;
		// 添加新建事件按钮和删除事件
		if (!this.data && insertAction) {
			var insertBtn = new Ext.Button({
						iconCls : 'icon-add',
						xtype : 'button',
						text : '新建'
					});
			insertBtn.addListener('click', function(btn) {
						if (!this.beforeInsert
								|| (typeof(this.beforeInsert) == 'function' && this
										.beforeInsert())) {
							var recordMapping = [];
							for (var i = 0; i < this.metaData.length; i++) {
								if (this.metaData[i].name) {
									recordMapping.push({
												name : this.metaData[i].name,
												type : this.metaData[i].type
											});
								}
							}

							var TempRecord = Ext.data.Record
									.create(recordMapping);
							var recordArr = [];
							var record = this.getStore().getAt(0).copy();
							var idField = 'id';
							if (!record.get('id')) {
								idField = this.beanName + 'Id';
							}

							record.set(idField, null);
							recordArr.push(record);

							this.stopEditing();
							this.getStore().insert(0, recordArr);
							this.startEditing(0, 2);
						}
					}, this);

			buttonArr.push(insertBtn);
			empty = false;
		}
		// 添加删除事件按钮和删除事件
		if (deleteAction) {
			var deleteBtn = new Ext.Button({
						iconCls : 'icon-del',
						xtype : 'button',
						text : '删除'
					});
			deleteBtn.addListener('click', function(btn) {
				if (!this.beforeDelete
						|| (typeof(this.beforeDelete) == 'function' && this
								.beforeDelete())) {
					var selections = this.getSelectionModel().getSelections();
					if (selections.length == 0) {
						showWarningMsg('请首先选择记录再进行删除操作');
						return;
					}

					var idArr = [];
					for (var i = 0; i < selections.length; i++) {
						var id = selections[i].get('id');
						if (!id) {
							id = selections[i].get(this.beanName + 'Id');
						}
						idArr.push(id);
					}

					var grid = this;
					ajaxRequest(deleteAction, {
								id : idArr.join(',')
							}, this, function() {
								if (grid.afterDelete
										&& typeof(grid.afterDelete) == 'function') {
									grid.afterDelete();
								} else {
									grid.getStore().reload();
								}
							});
				}
			}, this);

			buttonArr.push(deleteBtn);
			empty = false;
		}

		// 设定的按钮
		if (this.tbar) {
			buttonArr.unshift(this.tbar);
		}

		var toolbar = new Ext.Toolbar(buttonArr);
		if (!empty) {
			Ext.apply(this, {
						tbar : toolbar
					});
		}

		Ext.apply(this, {					
					loadMask : {
						msg : '数据加载中...'
					},
					cm : cm,
					sm : sm,
					ds : ds,
					mode : mode,
					bodyStyle : 'width:100%',
					viewConfig : {
						forceFit : true
					},
					enableColumnMove : false,
					trackMouseOver : false,
					clicksToEdit : 1
				});
		if(!this.noIcon){
			Ext.apply(this, {
				iconCls : 'icon-grid'
			});
		}
		
		Ext.ux.SimpleEditorGridPanel.superclass.initComponent.call(this);

		// 添加更新事件
		if (updateAction || insertAction) {
			this.addListener('afteredit', function(e) {
				var id = e.record.get('id');
				if (!id) {
					id = e.record.get(this.beanName + 'Id');
				}
				if (Ext.isEmpty(id)) {
					ajaxRequest(insertAction, {
								fieldName : e.field,
								fieldValue : e.value
							}, this, function() {
								if (grid.afterInsert
										&& typeof(grid.afterInsert) == 'function') {
									grid.afterInsert();
								} else {
									grid.getStore().reload();
								}
							}, function() {
								e.record.reject();
							});
				} else {
					if (!this.beforeUpdate
							|| (typeof(this.beforeUpdate) == 'function' && this
									.beforeUpdate(e))) {
						ajaxRequest(updateAction, {
									fieldName : e.field,
									fieldValue : e.value,
									id : e.record.data.id
								}, this, function() {
									if (grid.afterUpdate
											&& typeof(grid.afterUpdate) == 'function') {
										grid.afterUpdate();
									} else {
										grid.getStore().reload();
									}
								}, function() {
									e.record.reject();
								});
					}
				}
			}, this);
		}

	}
});

// 注册组件
Ext.reg("simpleEditorGridPanel", Ext.ux.SimpleEditorGridPanel);

Ext.ux.SimpleEditorGridPanel.SINGLE_SELECT = 1;// 单选
Ext.ux.SimpleEditorGridPanel.MULTI_SELECT = 2;// 复选
Ext.ux.SimpleEditorGridPanel.CHECKBOX_SELECT = 3;// 包含复选框
